﻿#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

; #SingleInstance force
; 支持%A_ThisHotKey%
#usehook On
; 窗口标题的任意位置包含 WinTitle 才能匹配.
SetTitleMatchMode, 2
; 保持小键盘打开
SetNumLockState AlwaysOn

; 大小写切换=>中英文切换
; 同时在设置中取消shift键中英文切换功能，中英文混合输入的时候会好受一些
CapsLock::^Space
; ScopedLock转换按键避免丢失大小写转换
ScrollLock::CapsLock

; 在Poker2将LWin键换成了LAlt，并将LAlt换成了Fn
; 因此在大键盘上也取消了这个键，换成使用Alt-Tab
LWin::LCtrl
LWin & Tab::AltTab

>#c::Run shell:AppsFolder\Microsoft.WindowsAlarms_8wekyb3d8bbwe!App

; 打开菜单
!o::AppsKey

; Screen Shot
!2::!PrintScreen
!3::#PrintScreen
!4::
Send +#s
return

; Ctrl + Alt + d 快速输出时间
^!d::
    FormatTime, now_date, %A_Now%, yyyy-MM-dd HH:mm:ss ; 格式化当前时间
    Send, % now_date
Return

; ======= 窗口管理 =======

!t::
WinSet, Style, ^0xC00000, A
return

; F8 切换任务栏显示
!F8::
	VarSetCapacity( APPBARDATA, 36, 0 )
	IfWinNotExist, ahk_class Shell_TrayWnd
	{
		NumPut( (ABS_AlwaysOnTOP := 0x2), APPBARDATA, 32, "UInt" )           ;Enable "Always on top" (& disable auto-hide)
		DllCall( "Shell32.dll\SHAppBarMessage", "UInt", ( ABM_SETSTATE := 0xA ), "UInt", &APPBARDATA )
		WinShow ahk_class Shell_TrayWnd
	}
	else
	{
		NumPut( ( ABS_AUTOHIDE := 0x1 ), APPBARDATA, 32, "UInt" )            ;Disable "Always on top" (& enable auto-hide to hide Start button)
		DllCall( "Shell32.dll\SHAppBarMessage", "UInt", ( ABM_SETSTATE := 0xA ), "UInt", &APPBARDATA )
		WinHide ahk_class Shell_TrayWnd
	}
return

; ======= 透明度 =========

~RShift & WheelUp::
<!,::
; 透明度调整，增加。
WinGet, Transparent, Transparent,A
If (Transparent="")
  Transparent=255
  ;Transparent_New:=Transparent+10
  Transparent_New:=Transparent+20    ;透明度增加速度。
  If (Transparent_New > 254)
    Transparent_New =255
  WinSet,Transparent,%Transparent_New%,A
return

~RShift & WheelDown::
<!.::
WinGet, Transparent, Transparent,A
If (Transparent="")
  Transparent=255
  Transparent_New:=Transparent-20  ;透明度减少速度。
  ;msgbox,Transparent_New=%Transparent_New%
  If (Transparent_New < 30)    ;最小透明度限制。
    Transparent_New = 30
  WinSet,Transparent,%Transparent_New%,A
return

~Rshift & Mbutton::
<!/::
WinGet, Transparent, Transparent,A
WinSet,Transparent,255,A 
return

!'::
WinSet, AlwaysOnTop, toggle,A
WinGetTitle, getTitle, A
Winget, getTop,ExStyle,A
if (getTop & 0x8)
    TrayTip 已置顶 %getTitle%, Alt + ' 取消置顶,10,1
else
    TrayTip 取消置顶 %getTitle%, Alt + ' 置顶,10,1
return

; ====== Better Alt ==========

; Alt + 滚轮 切换应用
Alt & WheelDown::AltTab
Alt & WheelUp::ShiftAltTab

; Alt + JK 切换标签页
<!J::Send ^{Tab}
<!K::Send +^{Tab}

; Alt 方向
!w::Send {Up}
!s::Send {Down}
!a::Send {Left}
!d::Send {Right}
+!w::Send {WheelUp}
+!s::Send {WheelDown}

; 配合Wox
; 需要将Wox的快捷键设为 Ctrl + '
!>Space::Send ^'

;  Alt+c使窗口居中，对付那些大部分在屏幕外侧的窗口
!c::
    WinGetActiveTitle, cTitle
    WinGetPos,,, Width, Height, %cTitle%
    if ((A_ScreenWidth/2)-(Width/2) > 0 and (A_ScreenHeight/2)-(Height/2) > 0)
        WinMove, %cTitle%,, (A_ScreenWidth/2)-(Width/2), (A_ScreenHeight/2)-(Height/2)
    else
         WinMaximize, %cTitle%
 Return

+!d::send %A_YYYY%-%A_MM%-%A_DD%

; =========== Hot String ==============

::>[::「
::>]::」

; ========= Win10 虚拟桌面 ============

; Alt + [/] 切换到左/右虚拟桌面
RAlt & [:: Send #^{Left}
RAlt & ]:: Send #^{Right}

; 左手切换虚拟桌面
LAlt & q:: Send #^{Left}
LAlt & e:: Send #^{Right}

; Alt + ↑/↓ 新建/关闭虚拟桌面
RAlt & Up:: Send #^{d}
RAlt & Down:: Send #^{F4}

; Ctrl + ↑ 显示虚拟桌面管理
^Up:: Send #{Tab}
^Down::Send #{Tab}

; 配合 MoveToDesktop使用
; https://github.com/Eun/MoveToDesktop
#\::
; WinMenuSelectItem, A, , 1&, 2&
Send {Alt}{Space} 
Sleep 100
Send {Up}{Up}{Enter}
Send t
return

; ================ Console-like hotkey =============

; 命令提示符 is for windows-terminal default cmd title
^a::
if WinActive("C:\Windows\System32\cmd.exe") or WinActive("Windows PowerShell") or> WinActive("命令提示符")
{
  Send {Home}
  return
} else 
  Send %A_ThisHotkey%
return

^e:: 
if WinActive("C:\Windows\System32\cmd.exe") or WinActive("Windows PowerShell") or WinActive("命令提示符")
{
  Send {End}
  return
} else 
  Send %A_ThisHotkey%
return

^u::
if WinActive("C:\Windows\System32\cmd.exe") or WinActive("Windows PowerShell") or WinActive("命令提示符")
{
  Send ^{Home}
  return
} else 
  Send, %A_ThisHotkey%
return

^k::
if WinActive("C:\Windows\System32\cmd.exe") or WinActive("Windows PowerShell") or WinActive("命令提示符")
{
  Send ^{End}
  return
} else 
  Send, %A_ThisHotkey%
return

; ============= VIM ==============

vim_normal := false

$!`::
  if (vim_normal) {
    TrayTip, vim mode, "off", 10, 1
    vim_normal := false
  } else {
    TrayTip, vim mode, "on", 10, 1
    vim_normal := true
  }
  return

j::
  if (vim_normal) {
    Send {Down}
  } else 
    Send, {%A_ThisHotkey%}
  return
k::
  if (vim_normal) {
    Send {Up}
  } else
    Send, {%A_ThisHotkey%}
  return
h::
  if (vim_normal) {
    Send {Left}
  } else 
    Send, {%A_ThisHotkey%}
  return
l::
  if (vim_normal) {
    Send {Right}
  } else
    Send, {%A_ThisHotkey%}
  return

d::
  if (vim_normal) {
    Send {PgDn}
  } else 
    Send, {%A_ThisHotkey%}
  return
u::
  if (vim_normal) {
    Send {PgUp}
  } else
    Send, {%A_ThisHotkey%}
  return

; ============================================================================================================

; Shortcuts like mac
; Written by Bob
; http://www.cnblogs.com/Bob-wei/p/5316158.html

; Win+F1 to show HotkeyList
#F1::ListHotkeys

; ## Menu ##
<#H::WinMinimize, A
+<#H::HideOtherWindow()
<#Q::Send !{F4}
; File
<#T::Send ^t
; +<#T::Send +^t
<#R::Send ^r
<#N::Send ^n
<#O::Send ^o
<#W::Send ^w
<#S::Send ^s
<#P::Send ^p
; Edit
<#Z::Send ^z
+<#Z::Send ^y
<#X::Send ^x
<#C::Send ^c
<#V::Send ^v
!+<#V::
  clipboard = %clipboard%
  Send ^v
return
<#A::Send ^a
<#F::Send ^f
<#G::Send {F3}
+<#G::Send +{F3}
!<#F::Send ^h
; #Left::Send {Home}
; #Right::Send {End}
; #Up::Send {PgUp}
; #Down::Send {PgDn}
; !Left::Send ^{Left}
; !Right::Send ^{Right}
; #+Left::Send +{Home}
; #+Right::Send +{End}
; #+Up::Send +{PgUp}
; #+Down::Send +{PgDn}
!+Left::Send +^{Left}
!+Right::Send +^{Right}
; View
^<#F::Send {F11}
<#=::Send ^{WheelUp}
<#-::Send ^{WheelDown}
<#0::Send ^0
; Finder
<#Backspace::Send {Del}
+<#3::Send {PrintScreen}
+^<#3::Send {PrintScreen}
+<#4::Send !{PrintScreen}
+^<#4::Send !{PrintScreen}
<#F3::Send <#d
<#F10::Send {Volume_Mute}
<#F11::Send {Volume_Down}
<#F12::Send {Volume_Up}
<#+Backspace::EmptyBin()
; #+!Backspace::EmptyBin(true)




; ## functions ##
RunCmd(command)
{
  curPath := CurrentPath()
  Run %comspec% /K "cd /d "%curPath%" & %command%"
}

RunOrActivate(Program, isActivate=true, msg="")
{
  SplitPath, Program, ExeFile
  Process, Exist, %ExeFile%
  PID = %ErrorLevel%
  if (PID = 0) {
    Run, %Program%
  } else if (StrLen(msg) > 0) {
    MsgBox ,,AHK,%msg%,3
  }
  if (isActivate)
  {
    WinActivate, ahk_pid %PID%
  }
}

EmptyBin(isNoConfirm=false)
{
  ;SHERB_NOCONFIRMATION = 0x000001;
  ;SHERB_NOPROGRESSUI = 0x000002;
  ;SHERB_NOSOUND = 0x000004;
  dwFlags = 0x00
  if(isNoConfirm) {
    dwFlags = 0x01
  }
  DllCall("Shell32\SHEmptyRecycleBin", "Ptr", hwnd, "Ptr", NULL, "UInt", dwFlags)
}

HideOtherWindow()
{
  WinGetActiveTitle, curtitle
  Send #m
  Sleep,200
  WinRestore, %curtitle%
}

CurrentPath()
{
  url := GetCurrentExplorerURL(true)
  if (url)
    return ConvertExplorerURLToPath(url)
  return A_Desktop
}

GetCurrentExplorerURL(getLastWhenNoFound=false)
{
  WinGet, curhwnd, ID, A
  for pExp in ComObjCreate("Shell.Application").Windows
  {
    if (pExp.FullName = "C:\WINDOWS\EXPLORER.EXE") {
      if (pExp.hwnd = curhwnd) {
        return pExp.LocationURL
      }
      if(StrLen(pExp.LocationURL)> 0) {
        last := pExp.LocationURL
      }
    }
  }
  if(getLastWhenNoFound and last) {
    return last
  }
}

ConvertExplorerURLToPath(url)
{
  If !url
    Return ""
  path := url
  path := RegExReplace(path, "ftp://.*@","ftp://")
  StringReplace, pathj, path, file:///
  StringReplace, path, path, /, \, All
  Loop
    If RegExMatch(path, "i)(?<=%)[\da-f]{1,2}", hex)
      StringReplace, path, path, `%%hex%, % Chr("0x" . hex), All
    Else Break
  Return path 
}
